import { _decorator, Node, Label } from 'cc';
import { BaseView } from '../../../../scripts/libs/rxjs/cc3/BaseView';
import { Sprite } from 'cc';
import { ReactiveNumber } from '../../../../scripts/libs/rxjs/cc3/ReactiveNumber';
import { AxisLockType, AxisLockTypeTxt, Colors, isClaw, shapeInfoMap } from '../../game/basic';
import { MergeASAP } from '../../../../scripts/libs/rxjs/cc3/Merge';
import { ReactiveProperty } from '../../../../scripts/libs/rxjs/cc3/ReactiveProperty';
import { SpriteAtlas } from 'cc';
import { EditorStageView } from './EditorStageView';
import { UITransform } from 'cc';
import { gm } from '../../../../scripts/managers/GameManager';
import { Prefab } from 'cc';
import { instantiate } from 'cc';
import { color } from 'cc';
import { Color } from 'cc';
import { SpriteFrame } from 'cc';
const { ccclass, property, executeInEditMode } = _decorator;

@ccclass('EditorBlock')
@executeInEditMode
export class EditorBlock extends BaseView {

    posId = ReactiveProperty.Create<number>(null);

    blockId = ReactiveProperty.Create<number>(null);

    @property(ReactiveNumber)
    _shapeId: ReactiveNumber = ReactiveNumber.DefaultValue(0);
    @property({ slide: true, range: [0, 35, 1] })
    get shapeId(): number { return this._shapeId.value }
    set shapeId(v: number) { this._shapeId.Value = v; }

    @property(SpriteAtlas)
    atlas: SpriteAtlas = null;

    @property(Node)
    shapeRoot: Node = null;

    @property(Node)
    keyRoot: Node = null;

    @property(Label)
    infoLabel: Label = null;

    layer = ReactiveProperty.Create<number>(0);

    group = ReactiveProperty.Create<number>(null);

    @property(ReactiveNumber)
    _colorId: ReactiveNumber = ReactiveNumber.DefaultValue(0);
    @property({ slide: true, range: [0, 15, 1] })
    get colorId(): number { return this._colorId.value }
    set colorId(v: number) { this._colorId.Value = v; }

    @property(ReactiveNumber)
    _axisLock: ReactiveNumber = ReactiveNumber.DefaultValue(AxisLockType.None);
    @property({ type: AxisLockType })
    get axisLock(): AxisLockType { return this._axisLock.value }
    set axisLock(v: AxisLockType) { this._axisLock.Value = v; }

    axisLockParam = ReactiveProperty.Create<string>('');

    @property(Node)
    axisLockNode: Node = null;

    ice = ReactiveProperty.Create<number>(0);

    blind = ReactiveProperty.Create<number>(0);

    noBlindTxt = ReactiveProperty.Create<number>(0);

    keys = ReactiveProperty.Create<number[]>(null);

    lockerColor = ReactiveProperty.Create<number>(null); // 只有一个颜色值

    @property(Prefab)
    keyPrefab: Prefab = null;

    @property(Node)
    chainRoot: Node = null;

    @property(SpriteAtlas)
    chainAtlas: SpriteAtlas = null;

    @property(SpriteFrame)
    clawSpriteFrame: SpriteFrame = null;

    useObserves() {
        return [
            MergeASAP(this._shapeId, this._colorId).subscribe(this.refreshShape.bind(this)),
            MergeASAP(this.posId, this.blockId, this._colorId, this._axisLock, this.lockerColor, this.ice, this.blind, this.noBlindTxt).subscribe(this.refresh.bind(this)),
            gm.editAltPressed.subscribe(_ => this.infoLabel.node.active = gm.editAltPressed.value),
            this.layer.subscribe(this.layerChanged.bind(this)),
            this.keys.subscribe(this.refreshKeys.bind(this)),
        ];
    }

    refreshShape() {
        this.shapeRoot.destroyAllChildren();
        let shapeInfo = shapeInfoMap.get(this.shapeId);
        let center = shapeInfo.center;
        for (let i = 0; i < shapeInfo.data.length; i++) {
            let dataItem = shapeInfo.data[i];
            let posInt = [dataItem[0] - center[0], dataItem[1] - center[1]];
            let spriteNode = new Node(`sprite_${i}`);
            spriteNode.setParent(this.shapeRoot);
            let pos = EditorStageView.getPosByOffsetRowCol(posInt[0], posInt[1]);
            spriteNode.setPosition(pos);
            let sprite = spriteNode.addComponent(Sprite);
            let [shapeTexName, rotNumStr] = shapeInfo.tex[i].split('|');
            sprite.spriteFrame = this.atlas.getSpriteFrame(`editor/glass_fb_${shapeTexName}`);
            spriteNode.setRotationFromEuler(0, 0, 90 * Number(rotNumStr));
            let transform = spriteNode.getComponent(UITransform)
            sprite.sizeMode = Sprite.SizeMode.CUSTOM;
            transform.width = EditorStageView.Space.x;
            transform.height = EditorStageView.Space.y;
            sprite.type = Sprite.Type.SLICED;
            sprite.trim = false;
            if (isClaw(this.colorId)) {
                let clawNode = new Node(`claw`);
                clawNode.setParent(spriteNode);
                let clawSprite = clawNode.addComponent(Sprite);
                clawSprite.spriteFrame = this.clawSpriteFrame;
                clawSprite.color = Colors[this.colorId];
                clawNode.setWorldRotationFromEuler(0, 0, 0);
            }
        }
        this.refreshInfoPos();
        this.refreshKeys();
        this.refreshAxisPos();
        // this.refreshLockerPos();
    }

    refresh() {

        this.shapeRoot.getComponentsInChildren(Sprite).forEach(_ => {
            if (this.ice.value > 0) {
                _.color = Color.WHITE;
            } else {
                _.color = Colors[this.colorId]
            }
        })
        // this.shapeRoot.children.forEach(_ => {

        // });
        let infoText = `#${this.blockId.value}|S${this.shapeId}\nC${this.colorId}\nG${this.group.value}`;
        if (this.axisLock != AxisLockType.None) {
            infoText += `\n${AxisLockTypeTxt[this.axisLock]}`;
            this.axisLockNode.active = true;
            if (this.axisLock == AxisLockType.Horizontal) {
                this.axisLockNode.setRotationFromEuler(0, 0, 0);
            } else if (this.axisLock == AxisLockType.Vertical) {
                this.axisLockNode.setRotationFromEuler(0, 0, 90);
            }
        } else {
            this.axisLockNode.active = false;
        }
        // if (this.lockerColor.value > 0) {
        //     this.lockerNode.active = true;
        // } else {
        //     this.lockerNode.active = false;
        // }
        // this.lockerLabel.string = `C${this.lockerColor.value}`;
        let darker = color(Colors[this.lockerColor.value]);
        darker.r *= .5;
        darker.g *= .5;
        darker.b *= .5;
        // this.lockerLabel.outlineColor = darker;
        // this.lockerNode.getComponentInChildren(Sprite).color = Colors[this.lockerColor.value];

        this.infoLabel.string = infoText;

        let shapeInfo = shapeInfoMap.get(this.shapeId);
        if (this.lockerColor.value > 0) {
            this.shapeRoot.active = false;
            this.chainRoot.active = true;
            this.chainRoot.getComponent(Sprite).spriteFrame = this.chainAtlas.getSpriteFrame(`keylocker/chain_${shapeInfo.chainTex}`);
        } else {
            this.shapeRoot.active = true;
            this.chainRoot.active = false;
            this.chainRoot.getComponent(Sprite).spriteFrame = null;
        }
    }

    refreshInfoPos() {
        let shapeInfo = shapeInfoMap.get(this.shapeId);
        let center = shapeInfo.center;
        if (shapeInfo.data.length > 0) {
            let dataItem = shapeInfo.data[0];
            let posInt = [dataItem[0] - center[0], dataItem[1] - center[1]];
            let pos = EditorStageView.getPosByOffsetRowCol(posInt[0], posInt[1]);
            this.infoLabel.node.setPosition(pos);
        }
    }

    refreshAxisPos() {
        let shapeInfo = shapeInfoMap.get(this.shapeId);
        let c = shapeInfo.c;
        let center = shapeInfo.center;
        let posInt = [c[0] - center[0], c[1] - center[1]];
        let pos = EditorStageView.getPosByOffsetRowCol(posInt[0], posInt[1]);
        this.axisLockNode.setPosition(pos);
    }

    layerChanged() {
        let scale = Math.pow(.9, this.layer.value);
        this.node.setScale(scale, scale, scale);
    }

    refreshKeys() {
        this.keyRoot.destroyAllChildren();
        let shapeInfo = shapeInfoMap.get(this.shapeId);
        if (this.keys.value != null) {
            for (let i = 0; i < shapeInfo.data.length; i++) {
                let shapeItem = shapeInfo.data[i];
                let nailColor = this.keys.value[i];
                if (nailColor > 0) {
                    let nailNode = instantiate(this.keyPrefab);
                    nailNode.getComponent(Sprite).color = Colors[nailColor];
                    nailNode.setParent(this.keyRoot);
                    let posInt = [shapeItem[0] - shapeInfo.center[0], shapeItem[1] - shapeInfo.center[1]];
                    let pos = EditorStageView.getPosByOffsetRowCol(posInt[0], posInt[1]);
                    nailNode.setPosition(pos);
                }
            }
        }
    }

    // refreshLockerPos() {
    //     let shapeInfo = shapeInfoMap.get(this.shapeId);
    //     let c = shapeInfo.c;
    //     let center = shapeInfo.center;
    //     let posInt = [c[0] - center[0], c[1] - center[1]];
    //     let pos = EditorStageView.getPosByOffsetRowCol(posInt[0], posInt[1]);
    //     pos.y += 20;
    //     this.lockerNode.setPosition(pos);
    // }

}

